<?
    /* -*- Mode: PHP5; tab-width: 4; indent-tabs-mode: nil; basic-offset: 4 -*- */
    
    /*********************************************************
    *            --== InArch ==--
    *
    * This is the key class to all the admin side data nodes.
    * It is extended into child classes which do all the work.
    *
    * @author Kulikov Alexey <a.kulikov@gmail.com>
    * @version n/a
    * @since 08.08.2005
    * @copyright essentialmind.com 2005
    *
    *********************************************************/
    
    /***
    * Abstract Class installNode
    ****
    * This is the module installer/deinstaller, shall
    * automate integration of new modules into client
    * solutions
    ****
    * @package adminNodes
    * @author A Kulikov <a.kulikov@gmail.com>
    * @version n/a
    * @since 08.08.2005
    * @copyright essentialmind.com 2005
    ***/
    abstract class installNode{
    
        /**
         * reference to the ADODB Connection
         *
         * @var ADOConnection
         */
        protected $db;
        
        protected $log;     // reference to the log object
        protected $key;     
        protected $description;
        protected $isFolder = 'f';
        protected $adminadd = 't';
        

        /* --------------- END VARIABLE DECLARATION ----------------- */
        
        /**
         * Constructor
         * 
         * @param object $db     - Reference to the ADODB Connection
         * @param object $log    - Reference to log writer
         * @return void
         **/
        function __construct(ADOConnection $db, $log){
            $this->db       = $db;
            $this->log      = $log;
            $this->setKey();   
            $this->setProps();
        }
        
        
        /**
         * Process data structures creation of the node
         *
         */
        abstract protected function create();
        
        
        /**
         * Process data removal of the node
         *
         */
        abstract protected function remove();
        
        
        /**
         * Describe the class
         *
         */
        abstract protected function setProps();
        
        
        /**
         * Creates a node access record in the solution database
         *
         */
        final protected function createAccessRecord(){
            //insert access record into the datatype table
            $this->db->Execute("INSERT INTO datatype(name,codeset,folder,adminadd) 
                                VALUES('".$this->getDescription()."','".$this->getKey()."','".$this->getIsFolder()."','".$this->getAdminAdd()."')");
            
            return $this->db->getOne("SELECT max(id) FROM datatype");
        }
        
        
        /**
         * Removes the node access records from the solution database
         *
         */
        final protected function dropAccessRecord(){
            //delete access records from the datatype table
            $this->db->Execute("DELETE FROM datatype WHERE codeset = '".$this->getKey()."'");
        }
        
        
        /**
         * Install the node in a solution
         *
         */
        final public function install(){
            //runs inside a transaction
            $this->db->StartTrans();
            
            $this->create();
            $newRecordID = $this->createAccessRecord();
            $this->copyTemplates();
            
            $this->db->CompleteTrans();
            
            return $newRecordID;
        }
        
        
        /**
         * Uninstalls the node from the solution
         *
         */
        final public function uninstall(){
            //runs inside a transaction
            $this->db->StartTrans();
            
            $this->remove();
            $this->dropAccessRecord();
            // $this->dropTemplates();
            
            $this->db->CompleteTrans();
        }
        
        
        /**
         * Copies an instance of the template from the core to the
         * solution template root
         *
         * @param string $name
         */
        final protected function copyTemplate($name){
            
            $source = INA_ROOT.'templates'.DIRECTORY_SEPARATOR.'nodes'.DIRECTORY_SEPARATOR.$this->getKey().DIRECTORY_SEPARATOR.$name;
            $dest   = ROOT.'templates'.DIRECTORY_SEPARATOR.'main'.DIRECTORY_SEPARATOR.$name;
            
            //make sure this is NOT erroneous
            if(file_exists($source) and is_writable($dest)){
                copy($source,$dest);
            }
        }
        
        
        /**
         * Removes an instance of the template from the solution 
         * template root
         *
         * @param string $name
         */
        final protected function dropTemplate($name){
            $this->log->recordAction("Removed template - ".$name);
            @unlink(ROOT.'templates'.DIRECTORY_SEPARATOR.'main'.DIRECTORY_SEPARATOR.$name);
        }
        
        
        /**
         * Copies the whole template set ;)
         *
         */
        final protected function copyTemplates(){
                        
            $ina_source = INA_ROOT.'templates'.DIRECTORY_SEPARATOR.'nodes'.DIRECTORY_SEPARATOR.strtolower($this->getKey());
            $dest = ROOT.'templates'.DIRECTORY_SEPARATOR.'main';
            
            if(file_exists($ina_source) and is_writable($dest)){
                $fileSys = new fileSystem();
                $fileSys->copyDirs($ina_source,$dest);
            }
        }
        
        
        /**
         * Drops all the templates relevant to this node
         *
         */
        final protected function dropTemplates(){
            //yukk, we need to implement this   
        }
        
        
        /**
         * Sets the internal key pointer to the name of the instance of the class
         *
         */
        final protected function setKey(){
            $temp = substr(get_class($this),11);
            $temp[0] = strtolower($temp[0]);
            $this->key = $temp;
        }
        
        
        /**
         * Returns the internal key pointer
         *
         * @return string
         */
        final protected function getKey(){
            return $this->key;
        }
        
        
        /**
         * sets the description of the class
         *
         * @param string $desc
         */
        final protected function setDescription($desc){
            $this->description = $desc;   
        }
        
        
        /**
         * Returns the description of the calss
         *
         * @return string
         */
        final public function getDescription(){
            return $this->description;   
        }
        
        
        /**
         * Enter description here...
         *
         * @param bool $status
         */
        final public function setIsFolder($status=false){
            if($status){
                $this->isFolder = 't';   
            }else{
                $this->isFolder = 'f';   
            }
        }
        
        
        /**
         * Enter description here...
         *
         * @return bool
         */
        final public function getIsFolder(){
            return $this->isFolder;
        }
        
        
        /**
         * Enter description here...
         *
         * @param bool $status
         */
        final public function setAdminAdd($status=true){
            if($status){
                $this->adminadd = 't';
            }else{
                $this->adminadd = 'f';
            }
        }
        
        
        /**
         * Enter description here...
         *
         * @return bool
         */
        final public function getAdminAdd(){
            return $this->adminadd;   
        }
    }
?>